#include <vector>

#include "core.h"
#include "Option.h"
#include "Reader.h"

using namespace std;

void func_n(Option opt, const vector<string>& words) {
    if (opt.isDebug()) {
        cout << "List all word chains." << endl;
        cout << "----------------------------------------" << endl;
    }
    int len = (int) words.size();
    char *wordsArray[words.size()], *result[20000];
    for (int i = 0; i < len; i++) {
        wordsArray[i] = (char *) words[i].c_str();
    }
    int num = gen_chains_all(const_cast<char **>(wordsArray), len, result);
    cout << num << endl;
    if (num <= 20000) {
        for (int i = 0; i < num; i++) {
            cout << result[i] << endl;
        }
    }
}

void func_w(Option opt, const vector<string>& words) {
    if (opt.isDebug()) {
        cout << "Word chains with most words." << endl ;
        cout << "----------------------------------------" << endl;
    }
    int len = (int) words.size();
    char *wordsArray[words.size()], *result[20000];
    for (int i = 0; i < len; i++) {
        const string& str = words[i];
        wordsArray[i] = new char[str.length() + 1];
        strcpy(wordsArray[i], str.c_str());
    }
    int wordNum = gen_chain_word(const_cast<char **>(wordsArray),
                                 len,
                                 result,
                                 opt.getHeadChar(),
                                 opt.getTailChar(),
                                 opt.getRejectChar(),
                                 opt.allowCircles());
//    for (int i = 0; i < wordNum; i++) {
//        cout << result[i] << endl;
//    }
    fstream f;
    f.open("Solution.txt",ios::out);
    for (int i = 0; i < wordNum; i++) {
        f << result[i] << endl;
    }
    f.close();
}

void func_c(Option opt, const vector<string>& words) {
    if (opt.isDebug()) {
        cout << "Word chains with most letters." << endl;
        cout << "----------------------------------------" << endl;
    }
    int len = (int) words.size();
    char *wordsArray[words.size()], *result[20000];
    for (int i = 0; i < len; i++) {
        const string& str = words[i];
        wordsArray[i] = new char[str.length() + 1];
        strcpy(wordsArray[i], str.c_str());
    }
    int wordNum = gen_chain_char(const_cast<char **>(wordsArray), len,
                                 result,
                                 opt.getHeadChar(),
                                 opt.getTailChar(),
                                 opt.getRejectChar(),
                                 opt.allowCircles());
//    for (int i = 0; i < wordNum; i++) {
//        cout << result[i] << endl;
//    }
    fstream f;
    f.open("Solution.txt",ios::out);
    for (int i = 0; i < wordNum; i++) {
        f << result[i] << endl;
    }
    f.close();
}

int main(int argc, char *argv[]) {
    Option opt(argc, argv);
    if (opt.isError()) {
        return 1;
    }
    auto in = Reader(opt.getFileName());
    auto words = in.readAll();

    if (opt.isDebug()) {
        cout << endl << "-------------- Debugging ---------------" << endl;
        cout << "There are " << words.size() << " words int file " << opt.getFileName() <<  ": " << endl;
        for (const auto& word : words) {
            cout << " " << word << ",";
        }
        cout << endl << "----------------------------------------" << endl;
    }

    switch (opt.getFunction()) {
        case 1: // -n
            func_n(opt, words);
            break;
        case 2: // -w
            func_w(opt, words);
            break;
        case 3: // -c
            func_c(opt, words);
            break;
        default:
            break;
    }

    return 0;
}
